package com.bo.gather;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.bo.gather.bean.ContentBean;
import com.bo.gather.bean.GatherBean;
import com.bo.gather.rule.RuleAnalyse;
import com.bo.startup.Task;

public class GatherService {
	static Logger log = Logger.getLogger(GatherService.class.getName());
	/**
	 * 计算采集内容
	 * @param gatherbean
	 * @return
	 */
	public List<Map<String,String>> calculateGather(GatherBean gatherbean){
		List<Map<String,String>> resultlist=new ArrayList<Map<String,String>>();
		//计算父级内容
		this.calculateParentContent(gatherbean, resultlist);
		//计算子级内容
		if(resultlist.size()>0){
			this.calculateChildContent(gatherbean, resultlist);
			return resultlist;
		}
		return null;
	}
	public List<Map<String,String>> calculateSigleGather(GatherBean gatherbean,String url){
		List<Map<String,String>> resultlist=new ArrayList<Map<String,String>>();
		if(gatherbean.getParentUrl()!=null && gatherbean.getParentUrl().length>0){
			if(url!=null && !url.trim().equals("")){
				//计算父级内容
				this.calculateParentContent(gatherbean, resultlist,url);
			}
		}
		
		//计算子级内容
		if(resultlist.size()>0){
			this.calculateChildContent(gatherbean, resultlist);
			return resultlist;
		}
		return null;
	}
	/**
	 * 计算父级内容
	 * @param gatherbean
	 * @param resultlist
	 */
	public void calculateParentContent(GatherBean gatherbean,List<Map<String,String>> resultlist){
		if(gatherbean.getParentUrl()!=null && gatherbean.getParentUrl().length>0){
			for(String url:gatherbean.getParentUrl()){
				if(url!=null && !url.trim().equals("")){
					//计算父级html
					String patenthtml=this.getHtmlCode(url, gatherbean.getCode());
//					System.out.println(patenthtml);
					//提取范围html
					if(patenthtml!=null && gatherbean.getParentHtml()!=null && gatherbean.getParentHtml().getContentStart()!=null && gatherbean.getParentHtml().getContentEnd()!=null){
						String result=this.calculateContent(patenthtml,gatherbean.getParentHtml());
						if(result!=null && (result.equals(RuleAnalyse.delete) || result.equals(RuleAnalyse.alldelete) )){
							
						}else{
							patenthtml=result;
						}
					}
					//提取父级的内容
					List<ContentBean> parentList=gatherbean.getParentContent();
					if(patenthtml!=null && parentList!=null){
						List<String> htmlList=this.splitHtml(patenthtml, parentList);
						if(htmlList!=null && htmlList.size()>0){
							for(String html:htmlList){
								Map<String,String> resultMap=new HashMap<String,String>();
								boolean bo=true;
								for(ContentBean bean:parentList){
									String result=this.calculateContent(html,bean);
									if(result!=null){
										if(result.equals(RuleAnalyse.alldelete)){
											bo=false;
											break;
										}else if(result.equals(RuleAnalyse.delete)){
											continue;
										}else{
											resultMap.put(bean.getName(), result);
										}
									}
								}
								if(bo){
									resultlist.add(resultMap);
								}
							}
						}
					}
				}
			}
		}
	}
	/**
	 * 计算父级内容
	 * @param gatherbean
	 * @param resultlist
	 */
	public void calculateParentContent(GatherBean gatherbean,List<Map<String,String>> resultlist,String url){

		//计算父级html
		String patenthtml=this.getHtmlCode(url, gatherbean.getCode());
//		System.out.println(patenthtml);
		//提取范围html
		if(patenthtml!=null && gatherbean.getParentHtml()!=null && gatherbean.getParentHtml().getContentStart()!=null && gatherbean.getParentHtml().getContentEnd()!=null){
			String result=this.calculateContent(patenthtml,gatherbean.getParentHtml());
			if(result!=null && (result.equals(RuleAnalyse.delete) || result.equals(RuleAnalyse.alldelete) )){
				
			}else{
				patenthtml=result;
			}
		}
		//提取父级的内容
		List<ContentBean> parentList=gatherbean.getParentContent();
		if(patenthtml!=null && parentList!=null){
			List<String> htmlList=this.splitHtml(patenthtml, parentList);
			if(htmlList!=null && htmlList.size()>0){
				for(String html:htmlList){
					Map<String,String> resultMap=new HashMap<String,String>();
					boolean bo=true;
					for(ContentBean bean:parentList){
						String result=this.calculateContent(html,bean);
						if(result!=null){
							if(result.equals(RuleAnalyse.alldelete)){
								bo=false;
								break;
							}else if(result.equals(RuleAnalyse.delete)){
								continue;
							}else{
								resultMap.put(bean.getName(), result);
							}
						}
					}
					if(bo){
						resultlist.add(resultMap);
					}
				}
			}
		}
	
	}
	/**
	 * 计算子级内容
	 * @param gatherbean
	 * @param resultlist
	 */
	public void calculateChildContent(GatherBean gatherbean,List<Map<String,String>> resultlist){
		if(gatherbean.getChildUrl()!=null){
			Iterator<Map<String,String>> iterator=resultlist.iterator();
			while(iterator.hasNext()){
				Map<String,String> map=iterator.next();
				String url=map.get(gatherbean.getChildUrl());
				//计算子级html
				String childhtml=this.getHtmlCode(url, gatherbean.getCode());
				//提取范围html gather.child.html=
				if(gatherbean.getChildHtml()!=null){
					String result=this.calculateContent(childhtml,gatherbean.getChildHtml());
					if(result!=null){
						if(result.equals(RuleAnalyse.alldelete)){
							iterator.remove();
							continue;
						}else{
							childhtml=result;
						}
					}
				}
				
				//提取子级的内容
				List<ContentBean> childList=gatherbean.getChildContent();
				if(childList!=null){
					for(ContentBean bean:childList){
						String result=this.calculateContent(childhtml,bean);
						if(result!=null){
							if(result.equals(RuleAnalyse.alldelete)){
								iterator.remove();
								break;
							}else if(result.equals(RuleAnalyse.delete)){
								continue;
							}else{
								map.put(bean.getName(), result.trim());
							}
						}
					}
				}
			}
		}
	}
	
	
	
	/**
	 * 循环切割html内容
	 * @param html
	 * @param contentList
	 * @return
	 */
	private List<String> splitHtml(String html,List<ContentBean> contentList){
		//计算最后的位置
//		List<ContentBean> tempList=new ArrayList<ContentBean>();
//		ContentBean starttemp=null;
		ContentBean endtemp=null;
		int e=0;
//		int s=0;
		for(ContentBean bean:contentList){
			if(bean.getContentStart()!=null && bean.getContentEnd()!=null){
				int index=html.indexOf(bean.getContentStart());
				if(index>e){
					e=index;
					endtemp=bean;
				}
//				if(s==0){
//					s=index;
//					starttemp=bean;
//				}
//				if(index<s){
//					s=index;
//					starttemp=bean;
//				}
				
			}
		}
		//切分位置
		if( endtemp!=null){
			List<String> list=new ArrayList<String>();
//			while(true){
//				//取出最开始的位置
//				int indexstart=html.indexOf(endtemp.getContentStart());
//				if(indexstart!=-1){
//					String endstr=html.substring(indexstart+endtemp.getContentStart().length(),html.length());
//					int indexend=endstr.indexOf(endtemp.getContentEnd());
//					if(indexend!=-1){
//						int endsign=indexstart+1+endtemp.getContentStart().length()+indexend+1+endtemp.getContentEnd().length();
//						String content=html.substring(0,endsign);
//						list.add(content);
//						html=html.substring(endsign,html.length());
//					}
//				}else{
//					break;
//				}
//			}
			
			while(true){
				//取出最开始的位置
				int indexstart=html.indexOf(endtemp.getContentStart());
				if(indexstart!=-1){
					String endstr=html.substring(indexstart+endtemp.getContentStart().length(),html.length());
					int indexend=endstr.indexOf(endtemp.getContentEnd());
					if(indexend!=-1){
						int endsign=indexstart+endtemp.getContentStart().length()+indexend+endtemp.getContentEnd().length();
						String content=html.substring(0,endsign);
						list.add(content);
						html=html.substring(endsign,html.length());
					}
				}else{
					break;
				}
			}
			return list;
		}
		return null;
	}
	/**
	 * {replace:<div class="item">@@}{replace:<br />@@}
	 * {remove:QQ@@alldelete}{remove:qq@@alldelete}{remove:联系@@alldelete}
	 * {remove:电话@@alldelete}
	 * {length:>15;clean:[0-9]clean:[a-y]clean:[A-Y]clean:\\pP|\\pSclean: @@delete}
	 * @param html
	 * @param contentbean
	 * @return
	 */
	private String calculateContent(String html,ContentBean contentbean){
		if(contentbean.getContentStart()!=null && contentbean.getContentEnd()!=null){
			String htmlcontent=null;
			htmlcontent=this.getContent(html, contentbean.getContentStart(), contentbean.getContentEnd());
			//替换
			if(htmlcontent!=null && contentbean.getReplaceList()!=null){
				htmlcontent=RuleAnalyse.calculateReplace(htmlcontent, contentbean.getReplaceList());
                //专门为优酷而设计的 把"＂“　转为＂
                htmlcontent=htmlcontent.replaceAll("&ldquo;", "\"").replaceAll("&rdquo;", "\"")
                .replaceAll("&amp;quot;", "\"").replaceAll("&quot;", "\"");
                //&mdash;转为—
                htmlcontent=htmlcontent.replaceAll("&mdash;", "—");
//              ≤replace:%◎％≥    decode的话必须把%转换％
//              s=java.net.URLDecoder.decode(s, "utf-8");
                htmlcontent=htmlcontent.replaceAll("%", "％");
                htmlcontent=htmlcontent.replaceAll("&deg;", "°").replaceAll("&amp;", "&");
			}
			
			//删除
			if(htmlcontent!=null &&  contentbean.getRemoveList()!=null){
				String isdelete=RuleAnalyse.calculateRemove(htmlcontent, contentbean.getRemoveList());
				if(!RuleAnalyse.returnpass.equals(isdelete)){
					if(isdelete.equals(RuleAnalyse.delete)){
						return null;
					}else if(isdelete.equals(RuleAnalyse.alldelete)){
						return RuleAnalyse.alldelete;
					}
				}
			}
			//必须包含
			if(htmlcontent!=null &&  contentbean.getMustList()!=null){
				String isdelete=RuleAnalyse.calculateMustInfo(htmlcontent, contentbean.getMustList());
				if(!RuleAnalyse.returnpass.equals(isdelete)){
					if(isdelete.equals(RuleAnalyse.delete)){
						return null;
					}else if(isdelete.equals(RuleAnalyse.alldelete)){
						return RuleAnalyse.alldelete;
					}
				}
			}
			//验证长度
			//{length:<15;clean:[0-9]clean:[a-y]clean:[A-Y]clean:\\pP|\\pSclean: @@delete}
			if(htmlcontent!=null && contentbean.getLengthinfo()!=null){
				String isdelete=RuleAnalyse.calculateLength(htmlcontent, contentbean.getLengthinfo());
				if(!RuleAnalyse.returnpass.equals(isdelete)){
					if(isdelete.equals(RuleAnalyse.delete)){
						return null;
					}else if(isdelete.equals(RuleAnalyse.alldelete)){
						return RuleAnalyse.alldelete;
					}
				}
			}
			return htmlcontent;
		}
		return null;
	}
	
	/**
	 * <b>GET页面的内容</b>
	 * 
	 * @param cityMsg
	 * @return 返回HTML源代码
	 */
	private  String getHtmlCode(String url,String code) {
		
		String html=null;
		try{
			//为了避免并发量采集，睡眠半秒钟。
			Thread.sleep(500);
			 String sCurrentLine;  

			 StringBuffer sTotalString = new StringBuffer("");  

			 sCurrentLine="";  

			 java.io.InputStream l_urlStream;  
			 //cityMsg=java.net.URLEncoder.encode(cityMsg, "UTF-8");
			 java.net.URL l_url = new java.net.URL(url);  

			 java.net.HttpURLConnection l_connection = (java.net.HttpURLConnection) l_url.openConnection();
			 //l_connection.setRequestProperty("User-Agent","Mozilla/6.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			 int state=l_connection.getResponseCode();
			 if(state==200){
			 l_connection.connect();  

			 l_urlStream = l_connection.getInputStream();  

			 java.io.BufferedReader l_reader = new java.io.BufferedReader(new java.io.InputStreamReader(l_urlStream,code));  

			 //得到返回的信息
			 while ((sCurrentLine = l_reader.readLine()) != null) {  
			  sTotalString.append(sCurrentLine); 
			  sTotalString.append("\n");
			 }  
			 l_reader.close();
			 html = sTotalString.toString();
			
			 }else{
				 html=null;
			 }
			 l_connection.disconnect();
		}catch(Exception ex){
			log.error("读取网页异常："+url, ex);
		}
		return html;
	}
	
	/**
	 * <b>提取信息</b>
	 * @param htmltext
	 * @param start
	 * @param end
	 * @return
	 */
	private String getContent(String htmltext,String start,String end) {
		try{
		  int istart=htmltext.indexOf(start);
		  if(istart==-1){
//			  log.warn("截取失败开始标签为："+start+" 结束标签为： "+end);
//			  log.info(htmltext);
			  return null;
		  }
		  String temp=htmltext.substring(istart+start.length(), htmltext.length());
		  int iend=temp.indexOf(end);
		  if(iend==-1){
//			  log.warn("截取失败结束标签为："+end+"开始标签为："+start);
//			  log.info(htmltext);
			  return null;
		  }
		  return temp.substring(0,iend).trim();
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

}
